namespace SubhadraSolutions.Sharp.Logging.LogItems
{
    using System.Collections.Generic;
    using System.Dynamic;
    using System.Text;

    public sealed class ExpandoLogItem : DynamicObject
    {
        #region Fields

        private readonly SortedDictionary<string, object> _dictionary =
            new SortedDictionary<string, object>();

        #endregion Fields

        #region Properties

        public int Count
        {
            get { return _dictionary.Count; }
        }

        #endregion Properties

        #region Indexers

        public object this[string key]
        {
            get
            {
                object o;
                _dictionary.TryGetValue(key, out o);
                return o;
            }
            set { setValue(key, value); }
        }

        #endregion Indexers

        #region Methods

        public override IEnumerable<string> GetDynamicMemberNames()
        {
            return _dictionary.Keys;
        }

        public override string ToString()
        {
            var sb = new StringBuilder();
            foreach (var kvp in _dictionary)
            {
                sb.Append(kvp.Key);
                sb.Append("=");
                sb.Append(kvp.Value);
                sb.Append(", ");
            }
            if (sb.Length > 0)
            {
                sb.Length -= 2;
            }
            return sb.ToString();
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            return _dictionary.TryGetValue(binder.Name, out result);
        }

        public bool TryGetValue(string key, out object value)
        {
            return _dictionary.TryGetValue(key, out value);
        }

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            return setValue(binder.Name, value);
        }

        private bool setValue(string key, object value)
        {
            if (value == null)
            {
                return _dictionary.Remove(key);
            }
            _dictionary[key] = value;
            return true;
        }

        #endregion Methods
    }
}